package com.henghe.frame.core.advice;

import com.henghe.frame.common.exception.CustomerException;
import com.henghe.frame.common.exception.DecryException;
import com.henghe.frame.core.exception.AuthenticationException;
import com.henghe.frame.common.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2023/3/15 16:00
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class ExceptionAdivce {

    @Value("${henghe.show-error}")
    private Boolean showError;


    @ExceptionHandler(DecryException.class)
    public Result handleDecryException(DecryException e, HttpServletRequest request){
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',接口数据解密异常",requestURI,e);
        return Result.error("入参解密异常");
    }


    /**
     * 系统运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public Result handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生运行时系统异常", requestURI, e);
        if(!StringUtils.isEmpty(e.getMessage()) &&e.getMessage().contains("token已经过期")){
            return Result.authError("令牌过期，请重新登录");
        }
        if (showError) {
            return Result.error(e.getMessage().replaceAll("BusinessError: ", ""));
        } else {
            return Result.error("系统异常");
        }
    }

    @ExceptionHandler(CustomerException.class)
    public Result handleCustomerException(CustomerException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生运行时异常", requestURI, e);
        return Result.error(showError ? e.getMessage() : "系统异常");
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                      HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return Result.error(showError ? e.getMessage() : "系统异常");
    }


    /**
     * 全局捕获401异常
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(AuthenticationException.class)
    public Result authenticationException(Exception e) {
        if (e instanceof AuthenticationException) {
            return Result.authError(StringUtils.isEmpty(e.getMessage()) ? "验证失败" : e.getMessage());
        }
        return Result.authError(StringUtils.isEmpty(e.getMessage()) ? "系统异常" : e.getMessage());
    }


    /**
     * 全局捕获hibernate字段验证异常
     *
     * @param exception
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result methodArgumentNotValidException(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            if (errors != null) {
                errors.forEach(p -> {
                    FieldError fieldError = (FieldError) p;
                    stringBuilder.append("字段:[" + fieldError.getField() + "]" + fieldError.getDefaultMessage() + ",");
                });
            }
        }
        return Result.fieldError(stringBuilder.toString().substring(0, stringBuilder.toString().length() - 1));
    }

//    /**
//     * 系统运行时异常
//     */
//    @ExceptionHandler(Exception.class)
//    public Result handleException(RuntimeException e, HttpServletRequest request) {
//        String requestURI = request.getRequestURI();
//        log.error("请求地址'{}',发生异常", requestURI, e);
//        return Result.error(e.getMessage());
//    }


//    private <T> JsonResult<T> message(Integer code, String msg, T data) {
//        JsonResult<T> jsonResult = new JsonResult();
//        jsonResult.setCode(code);
//        jsonResult.setMsg(msg);
//        jsonResult.setData(data);
//        return jsonResult;
//    }
}
